package com.niudong.esdemo.LZ4IO;

import net.jpountz.lz4.*;
import org.apache.kafka.common.message.KafkaLZ4BlockInputStream;
import org.apache.kafka.common.message.KafkaLZ4BlockOutputStream;
import org.apache.lucene.codecs.compressing.CompressionMode;
import org.apache.lucene.codecs.compressing.Compressor;
import org.apache.lucene.codecs.compressing.Decompressor;
import org.apache.lucene.store.ByteArrayDataInput;
import org.apache.lucene.store.ByteArrayDataOutput;
import org.apache.lucene.util.BytesRef;
import org.junit.Test;

import java.io.*;
import java.util.Base64;

//案例: 字符高效流一次读写一行.
/*
    涉及到的方法:
        BufferedReader类中的特有方法:
            public String readLine();   //一次读取一行, 结束标记是"换行符", 并返回读取到的内容(不包括换行符), 读不到返回null
        BufferedWriter类中的特有方法:
            public void newLine();      //根据当前操作系统给出对应的换行符. windows(\r\n), linux(\n), mac(\r>
 */
public class Demo02 {

    @Test
    public void compress() throws Exception{
        //1. 创建输入流, 关联数据源文件.
        BufferedReader br = new BufferedReader(new FileReader("demo05/data/2.txt"));
        //2. 创建输出流, 关联目的地文件.
        BufferedWriter bw = new BufferedWriter(new FileWriter("demo05/data/3.txt"));
        //3. 定义变量, 记录读取到的内容(字节, 有效字节数, 字符, 有效字符数, 字符串).

        Compressor compressor = CompressionMode.HIGH_COMPRESSION.newCompressor();

        byte[] outPutBytes = new byte[8024];
        ByteArrayDataOutput dataOutput = new ByteArrayDataOutput(outPutBytes);
        String line = null;
        //4. 循环读取, 只要条件满足就一直读, 并将读取到的内容赋值给变量.
        while ((line = br.readLine()) != null) {
            //5. 将读取到的数据写入到 指定的目的地文件中.

            System.out.println(line);
            System.out.println(line.getBytes().length);


            byte[] bytes = line.getBytes("UTF-8");
            compressor.compress(bytes,0,bytes.length,dataOutput);

            System.out.println(dataOutput.getPosition());

            bw.append(new String(outPutBytes,0,dataOutput.getPosition(),"UTF-8"));
            System.out.println("压缩后：" +new String(outPutBytes,0,dataOutput.getPosition(),"UTF-8"));
            System.out.println("压缩后byte：" +new String(outPutBytes,0,dataOutput.getPosition(),"UTF-8").getBytes().length);
            dataOutput.reset(outPutBytes);
            bw.newLine();       //根据操作系统给出对应的换行符.
        }
        //6. 释放资源.
        br.close();
        bw.close();

    }

    @Test
    public void decompress() throws Exception{
        BufferedReader br = new BufferedReader(new FileReader("demo05/data/3.txt"));
        BufferedWriter bw   =new BufferedWriter(new FileWriter("demo05/data/4.txt"));
        Decompressor decompressor = CompressionMode.HIGH_COMPRESSION.newDecompressor();
        byte[] outPutBytes = new byte[8196];
        ByteArrayDataInput dataInput = new ByteArrayDataInput(outPutBytes);
        String line = null;
        while ((line = br.readLine()) != null) {
            System.out.println("字符：" +line.getBytes("UTF-8"));
            System.out.println("字符串byte长度：" +line.getBytes("UTF-8").length);
            byte[] bytes = line.getBytes("UTF-8");

            BytesRef ref = new BytesRef(8196);
            //decompressor.decompress(dataInput,bytes.length,0,bytes.length,ref);
            decompressor.decompress(dataInput,45,0,45,ref);
            System.out.println("解压字符串后：：" + ref.utf8ToString().length());

            bw.write(ref.utf8ToString());

            bw.newLine();
        }
        //6. 释放资源.
        bw.close();
        br.close();
    }


    /**
     * 压缩
     * @param data
     * @return
     * @throws IOException
     */
    public static String compress(String data) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        PrintWriter out = new PrintWriter(new KafkaLZ4BlockOutputStream(baos, 4));
        try {
            out.print(data);
            out.flush();
        } finally {
            if(out != null) {
                out.close();
            }
        }
        return Base64.getEncoder().encodeToString(baos.toByteArray());
    }

    /**
     * 解压缩
     * @param data
     * @return
     * @throws IOException
     */
    public static String deCompress(String data) throws IOException {
        byte[] source = Base64.getDecoder().decode(data);
        ByteArrayInputStream bais = new ByteArrayInputStream(source);
        BufferedReader br = new BufferedReader(new InputStreamReader(new KafkaLZ4BlockInputStream(bais)));
        StringBuffer sb = new StringBuffer();
        String str = null;
        try {
            while((str = br.readLine()) != null) {
                sb.append(str);
            }
        } finally {
            if(br != null) {
                br.close();
            }
        }
        return sb.toString();
    }

    @Test
    public void test02() throws Exception {
        System.out.println(compress("compresscompresscompress"));
    }
}
